package br.com.medmark.bean;

import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.servlet.http.HttpSession;

import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.ScheduleEntryResizeEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

import br.com.medmark.model.hibernate.AlocacaoProfissional;
import br.com.medmark.model.hibernate.Clinica;
import br.com.medmark.model.hibernate.Consulta;
import br.com.medmark.model.hibernate.Paciente;
import br.com.medmark.model.hibernate.Profissional;
import br.com.medmark.model.modelo.ConsultaModel;
import br.medmark.util.Constantes;
import br.medmark.util.Funcoes;
import br.medmark.util.Persistencia;

@ManagedBean(name = "beanConsultas")
@ViewScoped
public class BeanConsultas implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 8004854145905841563L;

	private ScheduleModel eventModel;
    
    private ScheduleModel lazyEventModel;
 
    private ScheduleEvent event = new DefaultScheduleEvent();
    
    private HttpSession session;
    
    private FacesContext facesContext;
 
    private List<Consulta> consultas;
    
    private Paciente paciente;
    
    private Profissional profissional;
    
    private String hora;
    
    private String data;
    
    private Consulta consulta;
    
    //--------------
    
    private Map<Profissional, List<ConsultaModel>> consultasModel = new HashMap<Profissional, List<ConsultaModel>>();
    private Map<String, List<ConsultaModel>> consultasModelS = new HashMap<String, List<ConsultaModel>>();
    
    private Set<Profissional> profissionaisConjuto = new HashSet<Profissional>();
    private Set<Entry<Profissional, List<ConsultaModel>>> entrySetConsultaPorProfissional;
    
	@PostConstruct
    public void init(){
    	
    	facesContext = FacesContext.getCurrentInstance();
		session = (HttpSession) facesContext.getExternalContext().getSession(true);
		
		Clinica clinica = (Clinica) session.getAttribute("clinica");
		if (clinica == null) {
			try {
				FacesContext.getCurrentInstance().getExternalContext().redirect("login/login.xhtml");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}else{
			consultas = Persistencia.getInstance().getConsultasPorStatus(clinica.getCodigo(),Constantes.STATUS_CONSULTA_CONFIRMADA);
	        eventModel = new DefaultScheduleModel();
	        
	        //---
	        
	        for (Consulta consulta : consultas) {
	        	String primeiroNomeProfissional = consulta.getSolicitacao().getHorario().getProfissional().getNome().split(" ")[0];
	        	DefaultScheduleEvent evento;
	        	if (consulta.getSolicitacao().getHorario().getTipoHorario() == Constantes.TIPO_HORARIO_ORDEM_CHEGADA) {
	        		evento = new DefaultScheduleEvent(primeiroNomeProfissional, consulta.getSolicitacao().getHorario().getHoraInicial(),consulta.getSolicitacao().getHorario().getHoraFinal());
				}else{
					evento = new DefaultScheduleEvent(primeiroNomeProfissional, consulta.getSolicitacao().getHorario().getDataConsulta(),consulta.getSolicitacao().getHorario().getDataConsulta());
				}
	        	evento.setId(String.valueOf(consulta.getCodigo()));
	        	evento.setData(consulta);
	        	eventModel.addEvent(evento);
	
	        	profissionaisConjuto.add(consulta.getSolicitacao().getHorario().getProfissional());
	        	
	        }
	        
	        HashMap<Integer,List<Consulta>> mapProfConsulta = new HashMap<Integer,List<Consulta>>();
	        List<AlocacaoProfissional> alocacoes = clinica.getAlocacoes();
	        if (alocacoes == null) {
				alocacoes = new ArrayList<AlocacaoProfissional>();
			}
	        for (AlocacaoProfissional alocacao : alocacoes) {
	        	
	        	List<Consulta> consultas = Persistencia.getInstance().getConsultasPorProfissional(clinica.getCodigo(), alocacao.getProfissional().getCodigo());
	        	
	        	mapProfConsulta.put(alocacao.getProfissional().getCodigo(), consultas);

	        	
	        
			}
	        
	        List<ConsultaModel> contultasPorProfissional = new ArrayList<ConsultaModel>();
	        
	        for (Integer codigoProfissional : mapProfConsulta.keySet()) {
	        	for (Consulta consultaProf : mapProfConsulta.get(codigoProfissional)) {
	        		
	        		String primeiroNomeProfissional = consultaProf.getSolicitacao().getHorario().getProfissional().getNome() .split(" ")[0];
		        	String nomePaciente = consultaProf.getSolicitacao().getPaciente().getNome().split(" ")[0];
		        	ConsultaModel modelo = new ConsultaModel(primeiroNomeProfissional, nomePaciente);
		        	
		        	Date date = null;
					try {
						date = Funcoes.formataData(Funcoes.dataString(consultaProf.getSolicitacao().getHorario()), "dd/MM/yyyy");
					} catch (ParseException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
		        	boolean ehMaiorIgual = true;
					try {
						ehMaiorIgual = Funcoes.diferencaMaiorIgualUmDia(date, Funcoes.formataData(Funcoes.getDataAtual(),"dd/MM/yyyy"));
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
		        	if (!ehMaiorIgual) {
		        		modelo.setHorario(Funcoes.horarioString(consultaProf.getSolicitacao().getHorario()));
		        		contultasPorProfissional.add(modelo);
					}
				}
	        	
	        	Profissional p = (Profissional) Persistencia.getInstance().consultarPorId(codigoProfissional, Profissional.class);
	        	this.consultasModelS.put(p.getNome(), contultasPorProfissional);
	        	
			}
	        
	      /* for (Profissional profissional : profissionaisConjuto) {
	    	   
	    	   List<ConsultaModel> contultasPorProfissional = new ArrayList<ConsultaModel>();
	    	   
	    	   */
	        	/*for (Consulta consulta : consultas) {
					if (profissional.getCodigo() == consulta.getSolicitacao().getHorario().getProfissional().getCodigo()){
						String primeiroNomeProfissional = consulta.getSolicitacao().getHorario().getProfissional().getNome().split(" ")[0];
			        	String nomePaciente = consulta.getSolicitacao().getPaciente().getNome().split(" ")[0];
			        	
						ConsultaModel modelo = new ConsultaModel(primeiroNomeProfissional, nomePaciente);
					//	modelo.setHorarioInicial(consulta.getSolicitacao().getHorario().getHoraInicial());
					//	modelo.setHorarioFinal(consulta.getSolicitacao().getHorario().getHoraFinal());
						
						Date date = null;
						try {
							date = Funcoes.formataData(Funcoes.dataString(consulta.getSolicitacao().getHorario()), "dd/MM/yyyy");
						} catch (ParseException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						}
			        	boolean ehMaiorIgual = true;
						try {
							ehMaiorIgual = Funcoes.diferencaMaiorIgualUmDia(date, Funcoes.formataData(Funcoes.getDataAtual(),"dd/MM/yyyy"));
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
			        	if (!ehMaiorIgual) {
			        		modelo.setHorario(Funcoes.horarioString(consulta.getSolicitacao().getHorario()));
			        		contultasPorProfissional.add(modelo);
						}
						//contultasPorProfissional.add(modelo);
					}
				}
	        	this.consultasModelS.put(profissional.getNome(), contultasPorProfissional);
	        }*/
       
		}
    }   
       
    public void cancelarConsulta() throws Exception{
    	 
    	Consulta consulta = ((Consulta) event.getData());
    	consulta.setStatus(Constantes.STATUS_CONSULTA_CANCELADA);
    	consulta.getSolicitacao().getHorario().setNumeroVagas(consulta.getSolicitacao().getHorario().getNumeroVagas()+1);
    	Persistencia.getInstance().atualizar(consulta);
    	
    	eventModel.deleteEvent(event);
    	
    }
    
    public void marcarComoRealizada() throws Exception{
   	 
    	Consulta consulta = ((Consulta) event.getData());
    	consulta.setStatus(Constantes.STATUS_CONSULTA_REALIZADA);
    	Persistencia.getInstance().atualizar(consulta);
    	
    	eventModel.deleteEvent(event);
    	
    }
    
    public ScheduleModel getEventModel() {
        return eventModel;
    }
     
    public ScheduleModel getLazyEventModel() {
        return lazyEventModel;
    }
 
    private Calendar today() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
 
        return calendar;
    }
     
    
     
    public ScheduleEvent getEvent() {
        return event;
    }
 
    public void setEvent(ScheduleEvent event) {
        this.event = event;
    }
     
    public void addEvent(ActionEvent actionEvent) {
        if(event.getId() == null)
            eventModel.addEvent(event);
        else
            eventModel.updateEvent(event);
         
        event = new DefaultScheduleEvent();
    }
     
    public void onEventSelect(SelectEvent selectEvent) {
        event = (ScheduleEvent) selectEvent.getObject();
        paciente = ((Consulta)event.getData()).getSolicitacao().getPaciente();
        profissional = ((Consulta)event.getData()).getSolicitacao().getHorario().getProfissional();
        hora = Funcoes.horarioString(((Consulta)event.getData()).getSolicitacao().getHorario());
        data = Funcoes.dataString(((Consulta)event.getData()).getSolicitacao().getHorario());
        consulta = ((Consulta)event.getData());
        
    }
     
    public void onDateSelect(SelectEvent selectEvent) {
        event = new DefaultScheduleEvent("", (Date) selectEvent.getObject(), (Date) selectEvent.getObject());
    }
     
    public void onEventMove(ScheduleEntryMoveEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event moved", "Day delta:" + event.getDayDelta() + ", Minute delta:" + event.getMinuteDelta());
         
        addMessage(message);
    }
     
    public void onEventResize(ScheduleEntryResizeEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event resized", "Day delta:" + event.getDayDelta() + ", Minute delta:" + event.getMinuteDelta());
         
        addMessage(message);
    }
     
    private void addMessage(FacesMessage message) {
        FacesContext.getCurrentInstance().addMessage(null, message);
    }

	public List<Consulta> getConsultas() {
		return consultas;
	}

	public void setConsultas(List<Consulta> consultas) {
		this.consultas = consultas;
	}

	public Paciente getPaciente() {
		return paciente;
	}

	public void setPaciente(Paciente paciente) {
		this.paciente = paciente;
	}

	public Profissional getProfissional() {
		return profissional;
	}

	public void setProfissional(Profissional profissional) {
		this.profissional = profissional;
	}

	public String getHora() {
		return hora;
	}

	public void setHora(String hora) {
		this.hora = hora;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}

	public void setEventModel(ScheduleModel eventModel) {
		this.eventModel = eventModel;
	}

	public Set<Profissional> getProfissionaisConjuto() {
		return profissionaisConjuto;
	}

	public void setProfissionaisConjuto(Set<Profissional> profissionaisConjuto) {
		this.profissionaisConjuto = profissionaisConjuto;
	}

	public Map<Profissional, List<ConsultaModel>> getConsultasModel() {
		return consultasModel;
	}

	public void setConsultasModel(Map<Profissional, List<ConsultaModel>> consultasModel) {
		this.consultasModel = consultasModel;
	}

	public Set<Entry<Profissional, List<ConsultaModel>>> getEntrySetConsultaPorProfissional() {
		return entrySetConsultaPorProfissional;
	}

	public void setEntrySetConsultaPorProfissional(
			Set<Entry<Profissional, List<ConsultaModel>>> entrySetConsultaPorProfissional) {
		this.entrySetConsultaPorProfissional = entrySetConsultaPorProfissional;
	}

	public Map<String, List<ConsultaModel>> getConsultasModelS() {
		return consultasModelS;
	}

	public void setConsultasModelS(Map<String, List<ConsultaModel>> consultasModelS) {
		this.consultasModelS = consultasModelS;
	}
	
	
}
